home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / sdcparam.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  17.5 KB  |  621 lines

  1. /* Copyright (C) 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: sdcparam.c,v 1.2 2000/09/19 19:00:49 lpd Exp $ */
  20. /* DCT filter parameter setting and reading */
  21. #include "memory_.h"
  22. #include "jpeglib_.h"
  23. #include "gserror.h"
  24. #include "gserrors.h"
  25. #include "gstypes.h"
  26. #include "gsmemory.h"
  27. #include "gsparam.h"
  28. #include "strimpl.h"        /* sdct.h requires this */
  29. #include "sdct.h"
  30. #include "sdcparam.h"
  31. #include "sjpeg.h"
  32.  
  33. /* Define the DCT parameters. */
  34. #define dctp(key, type, stype, memb) { key, type, offset_of(stype, memb) }
  35. private const gs_param_item_t s_DCT_param_items[] =
  36. {
  37. dctp("ColorTransform", gs_param_type_int, stream_DCT_state, ColorTransform),
  38.     dctp("QFactor", gs_param_type_float, stream_DCT_state, QFactor),
  39.     gs_param_item_end
  40. };
  41. private const gs_param_item_t jsd_param_items[] =
  42. {
  43.     dctp("Picky", gs_param_type_int, jpeg_stream_data, Picky),
  44.     dctp("Relax", gs_param_type_int, jpeg_stream_data, Relax),
  45.     gs_param_item_end
  46. };
  47.  
  48. #undef dctp
  49.  
  50. /*
  51.  * Adobe specifies the values to be supplied in zigzag order.
  52.  * For IJG versions newer than v6, we need to convert this order
  53.  * to natural array order.  Older IJG versions want zigzag order.
  54.  */
  55. #if JPEG_LIB_VERSION >= 61
  56.     /* natural array position of n'th element of JPEG zigzag order */
  57. static const byte natural_order[DCTSIZE2] =
  58. {
  59.     0, 1, 8, 16, 9, 2, 3, 10,
  60.     17, 24, 32, 25, 18, 11, 4, 5,
  61.     12, 19, 26, 33, 40, 48, 41, 34,
  62.     27, 20, 13, 6, 7, 14, 21, 28,
  63.     35, 42, 49, 56, 57, 50, 43, 36,
  64.     29, 22, 15, 23, 30, 37, 44, 51,
  65.     58, 59, 52, 45, 38, 31, 39, 46,
  66.     53, 60, 61, 54, 47, 55, 62, 63
  67. };
  68.  
  69. #define jpeg_order(x)  natural_order[x]
  70.     /* invert natural_order for getting parameters */
  71. static const byte inverse_natural_order[DCTSIZE2] =
  72. {
  73.     0, 1, 5, 6, 14, 15, 27, 28,
  74.     2, 4, 7, 13, 16, 26, 29, 42,
  75.     3, 8, 12, 17, 25, 30, 41, 43,
  76.     9, 11, 18, 24, 31, 40, 44, 53,
  77.     10, 19, 23, 32, 39, 45, 52, 54,
  78.     20, 22, 33, 38, 46, 51, 55, 60,
  79.     21, 34, 37, 47, 50, 56, 59, 61,
  80.     35, 36, 48, 49, 57, 58, 62, 63
  81. };
  82.  
  83. #define jpeg_inverse_order(x)  inverse_natural_order[x]
  84. #else
  85. #define jpeg_order(x)  (x)
  86. #define jpeg_inverse_order(x) (x)
  87. #endif
  88.  
  89. /* ================ Get parameters ================ */
  90.  
  91. private int
  92. quant_param_string(gs_param_string * pstr, int count, const UINT16 * pvals,
  93.            floatp QFactor, gs_memory_t * mem)
  94. {
  95.     byte *data;
  96.     int code = 0;
  97.     int i;
  98.  
  99.     data = gs_alloc_string(mem, count, "quant_param_string");
  100.     if (data == 0)
  101.     return_error(gs_error_VMerror);
  102.     for (i = 0; i < count; ++i) {
  103.     floatp val = pvals[jpeg_inverse_order(i)] / QFactor;
  104.  
  105.     data[i] =
  106.         (val < 1 ? (code = 1) : val > 255 ? (code = 255) : (byte) val);
  107.     }
  108.     pstr->data = data;
  109.     pstr->size = count;
  110.     pstr->persistent = true;
  111.     return code & 1;
  112. }
  113.  
  114. private int
  115. quant_param_array(gs_param_float_array * pfa, int count, const UINT16 * pvals,
  116.           floatp QFactor, gs_memory_t * mem)
  117. {
  118.     float *data;
  119.     int i;
  120.  
  121.     data = (float *)gs_alloc_byte_array(mem, count, sizeof(float),
  122.                     "quant_param_array");
  123.  
  124.     if (data == 0)
  125.     return_error(gs_error_VMerror);
  126.     for (i = 0; i < count; ++i)
  127.     data[i] = pvals[jpeg_inverse_order(i)] / QFactor;
  128.     pfa->data = data;
  129.     pfa->size = count;
  130.     pfa->persistent = true;
  131.     return 0;
  132. }
  133.  
  134. int
  135. s_DCT_get_quantization_tables(gs_param_list * plist,
  136.        const stream_DCT_state * pdct, const stream_DCT_state * defaults,
  137.                   bool is_encode)
  138. {
  139.     gs_memory_t *mem = pdct->memory;
  140.     jpeg_component_info d_comp_info[4];
  141.     int num_in_tables;
  142.     const jpeg_component_info *comp_info;
  143.     const jpeg_component_info *default_comp_info;
  144.     JQUANT_TBL **table_ptrs;
  145.     JQUANT_TBL **default_table_ptrs;
  146.     gs_param_array quant_tables;
  147.     floatp QFactor = pdct->QFactor;
  148.     int i;
  149.     int code;
  150.  
  151.     if (is_encode) {
  152.     num_in_tables = pdct->data.compress->cinfo.num_components;
  153.     comp_info = pdct->data.compress->cinfo.comp_info;
  154.     table_ptrs = pdct->data.compress->cinfo.quant_tbl_ptrs;
  155.     if (defaults) {
  156.         default_comp_info = defaults->data.compress->cinfo.comp_info;
  157.         default_table_ptrs = defaults->data.compress->cinfo.quant_tbl_ptrs;
  158.     }
  159.     } else {
  160.     /**************** quant_tables.size NOT INITIALIZED ****************/
  161.     num_in_tables = quant_tables.size;
  162.     for (i = 0; i < num_in_tables; ++i)
  163.         d_comp_info[i].quant_tbl_no = i;
  164.     comp_info = d_comp_info;
  165.     table_ptrs = pdct->data.decompress->dinfo.quant_tbl_ptrs;
  166.     if (defaults) {
  167.         default_comp_info = d_comp_info;
  168.         default_table_ptrs =
  169.         defaults->data.decompress->dinfo.quant_tbl_ptrs;
  170.     }
  171.     }
  172.  
  173.     /* Check whether all tables match defaults. */
  174.     if (defaults) {
  175.     bool match = true;
  176.  
  177.     for (i = 0; i < num_in_tables; ++i) {
  178.         JQUANT_TBL *tbl = table_ptrs[comp_info[i].quant_tbl_no];
  179.         JQUANT_TBL *default_tbl =
  180.         (default_comp_info == 0 || default_table_ptrs == 0 ? 0 :
  181.          default_table_ptrs[default_comp_info[i].quant_tbl_no]);
  182.  
  183.         if (tbl == default_tbl)
  184.         continue;
  185.         if (tbl == 0 || default_tbl == 0 ||
  186.         memcmp(tbl->quantval, default_tbl->quantval,
  187.                DCTSIZE2 * sizeof(UINT16))
  188.         ) {
  189.         match = false;
  190.         break;
  191.         }
  192.     }
  193.     if (match)
  194.         return 0;
  195.     }
  196.     quant_tables.size = num_in_tables;
  197.     code = param_begin_write_collection(plist, "QuantTables",
  198.                     &quant_tables,
  199.                     gs_param_collection_array);
  200.     if (code < 0)
  201.     return code;
  202.     for (i = 0; i < num_in_tables; ++i) {
  203.     char key[3];
  204.     gs_param_string str;
  205.     gs_param_float_array fa;
  206.  
  207.     sprintf(key, "%d", i);
  208.     if (QFactor == 1.0) {
  209.         code = quant_param_string(&str, DCTSIZE2,
  210.                 table_ptrs[comp_info[i].quant_tbl_no]->quantval,
  211.                       QFactor, mem);
  212.         switch (code) {
  213.         case 0:
  214.             code = param_write_string(quant_tables.list, key, &str);
  215.             if (code < 0)
  216.             return code;    /* should dealloc */
  217.             continue;
  218.         default:
  219.             return code;    /* should dealloc */
  220.         case 1:
  221.             break;
  222.         }
  223.         /* break const to free the string */
  224.         gs_free_string(mem, (byte *) str.data, str.size,
  225.                "quant_param_string");
  226.     }
  227.     code = quant_param_array(&fa, DCTSIZE2,
  228.                 table_ptrs[comp_info[i].quant_tbl_no]->quantval,
  229.                  QFactor, mem);
  230.     if (code < 0)
  231.         return code;    /* should dealloc */
  232.     code = param_write_float_array(quant_tables.list, key, &fa);
  233.     if (code < 0)
  234.         return code;    /* should dealloc */
  235.     }
  236.     return param_end_write_dict(plist, "QuantTables", &quant_tables);
  237. }
  238.  
  239. private int
  240. pack_huff_table(gs_param_string * pstr, const JHUFF_TBL * table,
  241.         gs_memory_t * mem)
  242. {
  243.     int total;
  244.     int i;
  245.     byte *data;
  246.  
  247.     for (i = 1, total = 0; i <= 16; ++i)
  248.     total += table->bits[i];
  249.     data = gs_alloc_string(mem, 16 + total, "pack_huff_table");
  250.     if (data == 0)
  251.     return_error(gs_error_VMerror);
  252.     memcpy(data, table->bits + 1, 16);
  253.     memcpy(data + 16, table->huffval, total);
  254.     pstr->data = data;
  255.     pstr->size = 16 + total;
  256.     pstr->persistent = true;
  257.     return 0;
  258. }
  259.  
  260. int
  261. s_DCT_get_huffman_tables(gs_param_list * plist,
  262.        const stream_DCT_state * pdct, const stream_DCT_state * defaults,
  263.              bool is_encode)
  264. {
  265.     gs_memory_t *mem = pdct->memory;
  266.     gs_param_string *huff_data;
  267.     gs_param_string_array hta;
  268.     int num_in_tables;
  269.     jpeg_component_info *comp_info;
  270.     JHUFF_TBL **dc_table_ptrs;
  271.     JHUFF_TBL **ac_table_ptrs;
  272.     int i;
  273.     int code = 0;
  274.  
  275.     if (is_encode) {
  276.     dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs;
  277.     ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs;
  278.     num_in_tables = pdct->data.compress->cinfo.input_components * 2;
  279.     comp_info = pdct->data.compress->cinfo.comp_info;
  280.     } else {
  281.     dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs;
  282.     ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs;
  283.     for (i = 2; i > 0; --i)
  284.         if (dc_table_ptrs[i - 1] || ac_table_ptrs[i - 1])
  285.         break;
  286.     num_in_tables = i * 2;
  287.     comp_info = NULL;    /* do not set for decompress case */
  288.     }
  289. /****** byte_array IS WRONG ******/
  290.     huff_data = (gs_param_string *)
  291.     gs_alloc_byte_array(mem, num_in_tables, sizeof(gs_param_string),
  292.                 "get huffman tables");
  293.     if (huff_data == 0)
  294.     return_error(gs_error_VMerror);
  295.     for (i = 0; i < num_in_tables; i += 2) {
  296.     if ((code = pack_huff_table(huff_data + i, ac_table_ptrs[i >> 1], mem)) < 0 ||
  297.         (code = pack_huff_table(huff_data + i + 1, dc_table_ptrs[i >> 1], mem))
  298.         )
  299.         break;
  300.     }
  301.     if (code < 0)
  302.     return code;
  303.     hta.data = huff_data;
  304.     hta.size = num_in_tables;
  305.     hta.persistent = true;
  306.     return param_write_string_array(plist, "HuffTables", &hta);
  307. }
  308.  
  309. int
  310. s_DCT_get_params(gs_param_list * plist, const stream_DCT_state * ss,
  311.          const stream_DCT_state * defaults)
  312. {
  313.     int code =
  314.     gs_param_write_items(plist, ss, defaults, s_DCT_param_items);
  315.  
  316.     if (code >= 0)
  317.     code = gs_param_write_items(plist, ss->data.common,
  318.                     (defaults ? defaults->data.common :
  319.                      NULL),
  320.                     jsd_param_items);
  321.     return code;
  322. }
  323.  
  324. /* ================ Put parameters ================ */
  325.  
  326. stream_state_proc_put_params(s_DCT_put_params, stream_DCT_state);    /* check */
  327.  
  328. /* ---------------- Utilities ---------------- */
  329.  
  330. /*
  331.  * Get N byte-size values from an array or a string.
  332.  * Used for HuffTables, HSamples, VSamples.
  333.  */
  334. int
  335. s_DCT_byte_params(gs_param_list * plist, gs_param_name key, int start,
  336.           int count, UINT8 * pvals)
  337. {
  338.     int i;
  339.     gs_param_string bytes;
  340.     gs_param_float_array floats;
  341.     int code = param_read_string(plist, key, &bytes);
  342.  
  343.     switch (code) {
  344.     case 0:
  345.         if (bytes.size < start + count) {
  346.         code = gs_note_error(gs_error_rangecheck);
  347.         break;
  348.         }
  349.         for (i = 0; i < count; ++i)
  350.         pvals[i] = (UINT8) bytes.data[start + i];
  351.         return 0;
  352.     default:        /* might be a float array */
  353.         code = param_read_float_array(plist, key, &floats);
  354.         if (!code) {
  355.         if (floats.size < start + count) {
  356.             code = gs_note_error(gs_error_rangecheck);
  357.             break;
  358.         }
  359.         for (i = 0; i < count; ++i) {
  360.             float v = floats.data[start + i];
  361.  
  362.             if (v < 0 || v > 255) {
  363.             code = gs_note_error(gs_error_rangecheck);
  364.             break;
  365.             }
  366.             pvals[i] = (UINT8) (v + 0.5);
  367.         }
  368.         }
  369.     }
  370.     if (code < 0)
  371.     param_signal_error(plist, key, code);
  372.     return code;
  373. }
  374.  
  375. /* Get N quantization values from an array or a string. */
  376. private int
  377. quant_params(gs_param_list * plist, gs_param_name key, int count,
  378.          UINT16 * pvals, floatp QFactor)
  379. {
  380.     int i;
  381.     gs_param_string bytes;
  382.     gs_param_float_array floats;
  383.     int code = param_read_string(plist, key, &bytes);
  384.  
  385.     switch (code) {
  386.     case 0:
  387.         if (bytes.size != count) {
  388.         code = gs_note_error(gs_error_rangecheck);
  389.         break;
  390.         }
  391.         for (i = 0; i < count; ++i) {
  392.         double v = bytes.data[i] * QFactor;
  393.  
  394.         pvals[jpeg_order(i)] =
  395.             (UINT16) (v < 1 ? 1 : v > 255 ? 255 : v + 0.5);
  396.         }
  397.         return 0;
  398.     default:        /* might be a float array */
  399.         code = param_read_float_array(plist, key, &floats);
  400.         if (!code) {
  401.         if (floats.size != count) {
  402.             code = gs_note_error(gs_error_rangecheck);
  403.             break;
  404.         }
  405.         for (i = 0; i < count; ++i) {
  406.             double v = floats.data[i] * QFactor;
  407.  
  408.             pvals[jpeg_order(i)] =
  409.             (UINT16) (v < 1 ? 1 : v > 255 ? 255 : v + 0.5);
  410.         }
  411.         }
  412.     }
  413.     if (code < 0)
  414.     param_signal_error(plist, key, code);
  415.     return code;
  416. #undef jpeg_order
  417. }
  418.  
  419. /* ---------------- Main procedures ---------------- */
  420.  
  421. /* Put common scalars. */
  422. int
  423. s_DCT_put_params(gs_param_list * plist, stream_DCT_state * pdct)
  424. {
  425.     int code =
  426.     gs_param_read_items(plist, pdct, s_DCT_param_items);
  427.  
  428.     if (code < 0)
  429.     return code;
  430.     code = gs_param_read_items(plist, pdct->data.common, jsd_param_items);
  431.     if (code < 0)
  432.     return code;
  433.     if (pdct->data.common->Picky < 0 || pdct->data.common->Picky > 1 ||
  434.     pdct->data.common->Relax < 0 || pdct->data.common->Relax > 1 ||
  435.     pdct->ColorTransform < -1 || pdct->ColorTransform > 2 ||
  436.     pdct->QFactor < 0.0 || pdct->QFactor > 1000000.0
  437.     )
  438.     return_error(gs_error_rangecheck);
  439.     return 0;
  440. }
  441.  
  442. /* Put quantization tables. */
  443. int
  444. s_DCT_put_quantization_tables(gs_param_list * plist, stream_DCT_state * pdct,
  445.                   bool is_encode)
  446. {
  447.     int code;
  448.     int i, j;
  449.     gs_param_array quant_tables;    /* array of strings/arrays */
  450.     int num_in_tables;
  451.     int num_out_tables;
  452.     jpeg_component_info *comp_info;
  453.     JQUANT_TBL **table_ptrs;
  454.     JQUANT_TBL *this_table;
  455.  
  456.     switch ((code = param_begin_read_dict(plist, "QuantTables",
  457.                       &quant_tables, true))
  458.     ) {
  459.     case 1:
  460.         return 0;
  461.     default:
  462.         return param_signal_error(plist, "QuantTables", code);
  463.     case 0:
  464.         ;
  465.     }
  466.     if (is_encode) {
  467.     num_in_tables = pdct->data.compress->cinfo.num_components;
  468.     if (quant_tables.size < num_in_tables)
  469.         return_error(gs_error_rangecheck);
  470.     comp_info = pdct->data.compress->cinfo.comp_info;
  471.     table_ptrs = pdct->data.compress->cinfo.quant_tbl_ptrs;
  472.     } else {
  473.     num_in_tables = quant_tables.size;
  474.     comp_info = NULL;    /* do not set for decompress case */
  475.     table_ptrs = pdct->data.decompress->dinfo.quant_tbl_ptrs;
  476.     }
  477.     num_out_tables = 0;
  478.     for (i = 0; i < num_in_tables; ++i) {
  479.     char istr[5];        /* i converted to string key */
  480.     UINT16 values[DCTSIZE2];
  481.  
  482.     sprintf(istr, "%d", i);
  483.     code = quant_params(quant_tables.list, istr, DCTSIZE2, values,
  484.                 pdct->QFactor);
  485.     if (code < 0)
  486.         return code;
  487.     /* Check for duplicate tables. */
  488.     for (j = 0; j < num_out_tables; j++) {
  489.         if (!memcmp(table_ptrs[j]->quantval, values, sizeof(values)))
  490.         break;
  491.     }
  492.     if (comp_info != NULL)
  493.         comp_info[i].quant_tbl_no = j;
  494.     if (j < num_out_tables)    /* found a duplicate */
  495.         continue;
  496.     if (++num_out_tables > NUM_QUANT_TBLS)
  497.         return_error(gs_error_rangecheck);
  498.     this_table = table_ptrs[j];
  499.     if (this_table == NULL) {
  500.         this_table = gs_jpeg_alloc_quant_table(pdct);
  501.         if (this_table == NULL)
  502.         return_error(gs_error_VMerror);
  503.         table_ptrs[j] = this_table;
  504.     }
  505.     memcpy(this_table->quantval, values, sizeof(values));
  506.     }
  507.     return 0;
  508. }
  509.  
  510. /* Put Huffman tables. */
  511. private int
  512. find_huff_values(JHUFF_TBL ** table_ptrs, int num_tables,
  513.            const UINT8 counts[16], const UINT8 * values, int codes_size)
  514. {
  515.     int j;
  516.  
  517.     for (j = 0; j < num_tables; ++j)
  518.     if (!memcmp(table_ptrs[j]->bits, counts, sizeof(counts)) &&
  519.         !memcmp(table_ptrs[j]->huffval, values,
  520.             codes_size * sizeof(values[0])))
  521.         break;
  522.     return j;
  523. }
  524. int
  525. s_DCT_put_huffman_tables(gs_param_list * plist, stream_DCT_state * pdct,
  526.              bool is_encode)
  527. {
  528.     int code;
  529.     int i, j;
  530.     gs_param_array huff_tables;
  531.     int num_in_tables;
  532.     int ndc, nac;
  533.     int codes_size;
  534.     jpeg_component_info *comp_info;
  535.     JHUFF_TBL **dc_table_ptrs;
  536.     JHUFF_TBL **ac_table_ptrs;
  537.     JHUFF_TBL **this_table_ptr;
  538.     JHUFF_TBL *this_table;
  539.     int max_tables = 2;        /* baseline limit */
  540.  
  541.     switch ((code = param_begin_read_dict(plist, "HuffTables",
  542.                       &huff_tables, true))
  543.     ) {
  544.     case 1:
  545.         return 0;
  546.     default:
  547.         return param_signal_error(plist, "HuffTables", code);
  548.     case 0:
  549.         ;
  550.     }
  551.     if (is_encode) {
  552.     num_in_tables = pdct->data.compress->cinfo.input_components * 2;
  553.     if (huff_tables.size < num_in_tables)
  554.         return_error(gs_error_rangecheck);
  555.     comp_info = pdct->data.compress->cinfo.comp_info;
  556.     dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs;
  557.     ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs;
  558.     if (pdct->data.common->Relax)
  559.         max_tables = max(pdct->data.compress->cinfo.input_components, 2);
  560.     } else {
  561.     num_in_tables = huff_tables.size;
  562.     comp_info = NULL;    /* do not set for decompress case */
  563.     dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs;
  564.     ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs;
  565.     if (pdct->data.common->Relax)
  566.         max_tables = NUM_HUFF_TBLS;
  567.     }
  568.     ndc = nac = 0;
  569.     for (i = 0; i < num_in_tables; ++i) {
  570.     char istr[5];        /* i converted to string key */
  571.     UINT8 counts[16], values[256];
  572.  
  573.     /* Collect the Huffman parameters. */
  574.     sprintf(istr, "%d", i);
  575.     code = s_DCT_byte_params(huff_tables.list, istr, 0, 16, counts);
  576.     if (code < 0)
  577.         return code;
  578.     for (codes_size = 0, j = 0; j < 16; j++)
  579.         codes_size += counts[j];
  580.     if (codes_size > 256 /*|| r_size(pa) != codes_size+16 */ )
  581.         return_error(gs_error_rangecheck);
  582.     code = s_DCT_byte_params(huff_tables.list, istr, 16, codes_size,
  583.                  values);
  584.     if (code < 0)
  585.         return code;
  586.     if (i & 1) {
  587.         j = find_huff_values(ac_table_ptrs, nac, counts, values,
  588.                  codes_size);
  589.         if (comp_info != NULL)
  590.         comp_info[i >> 1].ac_tbl_no = j;
  591.         if (j < nac)
  592.         continue;
  593.         if (++nac > NUM_HUFF_TBLS)
  594.         return_error(gs_error_rangecheck);
  595.         this_table_ptr = ac_table_ptrs + j;
  596.     } else {
  597.         j = find_huff_values(dc_table_ptrs, ndc, counts, values,
  598.                  codes_size);
  599.         if (comp_info != NULL)
  600.         comp_info[i >> 1].dc_tbl_no = j;
  601.         if (j < ndc)
  602.         continue;
  603.         if (++ndc > NUM_HUFF_TBLS)
  604.         return_error(gs_error_rangecheck);
  605.         this_table_ptr = dc_table_ptrs + j;
  606.     }
  607.     this_table = *this_table_ptr;
  608.     if (this_table == NULL) {
  609.         this_table = gs_jpeg_alloc_huff_table(pdct);
  610.         if (this_table == NULL)
  611.         return_error(gs_error_VMerror);
  612.         *this_table_ptr = this_table;
  613.     }
  614.     memcpy(this_table->bits, counts, sizeof(counts));
  615.     memcpy(this_table->huffval, values, codes_size * sizeof(values[0]));
  616.     }
  617.     if (nac > max_tables || ndc > max_tables)
  618.     return_error(gs_error_rangecheck);
  619.     return 0;
  620. }
  621.